﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using Otonomos.World;

namespace Test.Otonomos.World
{
    [TestClass]
    public class TestSimpleWall2D
    {
        [TestMethod]
        public void CreateWall()
        {
            var wall = new SimpleWall2D(new Point2D(0, 0), new Point2D(2, 2), WallType.SingleLeft);
            Assert.AreEqual(wall.Length, Math.Sqrt(8));
            Assert.AreEqual(wall.FirstPoint, Point2D.Origin);
            Assert.AreEqual(wall.SecondPoint, new Point2D(2, 2));
            Assert.AreEqual(wall.WallType, WallType.SingleLeft);
        }

        [TestMethod]
        public void DistanceBetweenLeftSidedWallAndPoint()
        {
            var wallLeft = new SimpleWall2D(new Point2D(0, 0), new Point2D(2, 2), WallType.SingleLeft);

            var point1 = new Point2D(2, 0);
            var point2 = new Point2D(2, 2);
            var point3 = new Point2D(0, 2);
            var point4 = new Point2D(-2, -2);
            var point5 = new Point2D(-2, 0);
            var point6 = new Point2D(12.34, 23.45);
            var point7 = new Point2D(1, 1);
            var point8 = new Point2D(23.45, 12.34);
            var point9 = new Point2D(0, -2);

            Assert.IsTrue(double.IsPositiveInfinity(wallLeft.Distance(point1)));
            Assert.AreEqual(wallLeft.Distance(point2), 0.0);
            Assert.AreEqual(wallLeft.Distance(point3), Math.Sqrt(2));
            Assert.AreEqual(wallLeft.Distance(point4), Math.Sqrt(8));
            Assert.AreEqual(wallLeft.Distance(point5), 2.0);
            Assert.AreEqual(wallLeft.Distance(point6), Math.Sqrt(10.34*10.34+21.45*21.45));
            Assert.AreEqual(wallLeft.Distance(point7), 0.0);
            Assert.IsTrue(double.IsPositiveInfinity(wallLeft.Distance(point8)));
            Assert.IsTrue(double.IsPositiveInfinity(wallLeft.Distance(point9)));
        }


        [TestMethod]
        public void DistanceBetweenRightSidedWallAndPoint()
        {
            var wallRight = new SimpleWall2D(new Point2D(2, 2), new Point2D(0, 0), WallType.SingleRight);

            var point1 = new Point2D(2, 0);
            var point2 = new Point2D(2, 2);
            var point3 = new Point2D(0, 2);
            var point4 = new Point2D(-2, -2);
            var point5 = new Point2D(-2, 0);
            var point6 = new Point2D(12.34, 23.45);
            var point7 = new Point2D(1, 1);
            var point8 = new Point2D(23.45, 12.34);
            var point9 = new Point2D(0, -2);

            Assert.IsTrue(double.IsPositiveInfinity(wallRight.Distance(point1)));
            Assert.AreEqual(wallRight.Distance(point2), 0.0);
            Assert.AreEqual(wallRight.Distance(point3), Math.Sqrt(2));
            Assert.AreEqual(wallRight.Distance(point4), Math.Sqrt(8));
            Assert.AreEqual(wallRight.Distance(point5), 2.0);
            Assert.AreEqual(wallRight.Distance(point6), Math.Sqrt(10.34 * 10.34 + 21.45 * 21.45));
            Assert.AreEqual(wallRight.Distance(point7), 0.0);
            Assert.IsTrue(double.IsPositiveInfinity(wallRight.Distance(point8)));
            Assert.IsTrue(double.IsPositiveInfinity(wallRight.Distance(point9)));
        }


        [TestMethod]
        public void DistanceBetweenDoubleSidedWallAndPoint()
        {
            var wall = new SimpleWall2D(new Point2D(0, 0), new Point2D(2, 2), WallType.DoubleSided);

            var point1 = new Point2D(2, 0);
            var point2 = new Point2D(2, 2);
            var point3 = new Point2D(0, 2);
            var point4 = new Point2D(-2, -2);
            var point5 = new Point2D(-2, 0);
            var point6 = new Point2D(12.34, 23.45);
            var point7 = new Point2D(1, 1);
            var point8 = new Point2D(23.45, 12.34);
            var point9 = new Point2D(0, -2);

            Assert.AreEqual(wall.Distance(point1), Math.Sqrt(2));
            Assert.AreEqual(wall.Distance(point2), 0.0);
            Assert.AreEqual(wall.Distance(point3), Math.Sqrt(2));
            Assert.AreEqual(wall.Distance(point4), Math.Sqrt(8));
            Assert.AreEqual(wall.Distance(point5), 2.0);
            Assert.AreEqual(wall.Distance(point6), Math.Sqrt(10.34 * 10.34 + 21.45 * 21.45));
            Assert.AreEqual(wall.Distance(point7), 0.0);
            Assert.AreEqual(wall.Distance(point8), Math.Sqrt(10.34 * 10.34 + 21.45 * 21.45));
            Assert.AreEqual(wall.Distance(point9), 2.0);
        }

        [TestMethod]
        public void Equality()
        {
            var wall = new SimpleWall2D(new Point2D(1, 1), new Point2D(3, 4), WallType.SingleRight);
            var otherWall = new SimpleWall2D(new Point2D(1, 1), new Point2D(3, 4), WallType.SingleRight);
            Assert.IsTrue(wall == otherWall);
        }
    }
}
